package com.hyperf.core.snowflake.worker;

import org.apache.curator.framework.CuratorFramework;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.data.Stat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author lizhaoyang
 */
public class ZookeeperWorkerRegister extends AbstractWorkerRegister {

    private static final Logger logger = LoggerFactory.getLogger(ZookeeperWorkerRegister.class);

    /**
     * 路径分隔符
     */
    private static final String PATH_SEPARATOR = "/";

    /**
     * Zookeeper根路径
     */
    private static final String BASE_PATH = "snowflake";

    /**
     * 路径前缀，/worker/[PROJECT]/
     */
    private static final String PATH_PREFIX = PATH_SEPARATOR + BASE_PATH + PATH_SEPARATOR;

    private CuratorFramework curatorFramework;

    public ZookeeperWorkerRegister(String applicationName, CuratorFramework curatorFramework) {
        super(applicationName);
        this.curatorFramework = curatorFramework;
    }

    @Override
    protected boolean doRegister(int workerId) {
        return createPath(workerId);
    }

    @Override
    protected void doDelete(int workerId) {
        String path = buildPath(workerId);
        deletePath(path);
    }

    /**
     * 创建路径
     *
     * @param workerId
     * @return
     */
    private boolean createPath(int workerId) {
        String path = buildPath(workerId);
        if (checkExists(path)) {
            return false;
        }

        try {
            curatorFramework.create().creatingParentsIfNeeded().withMode(CreateMode.EPHEMERAL).forPath(path);
            return true;
        } catch (Exception e) {
            if (logger.isErrorEnabled()) {
                logger.error("ZookeeperWorkerRegister createPath error, path: {}, error: {}", path, e);
            }
        }

        return false;
    }

    private void deletePath(String path) {
        try {
            curatorFramework.delete().forPath(path);
        } catch (Exception e) {
            if (logger.isErrorEnabled()) {
                logger.error("ZookeeperWorkerRegister deletePath error, path: {}, error: {}", path, e);
            }
        }
    }

    /**
     * 验证路径是否存在
     */
    private boolean checkExists(String path) {
        try {
            Stat stat = curatorFramework.checkExists().forPath(path);
            return stat != null;
        } catch (Exception e) {
            if (logger.isErrorEnabled()) {
                logger.error("ZookeeperWorkerRegister checkExists error, path: {}, error: {}", path, e);
            }
        }

        return true;
    }


    /**
     * 构造临时路径
     */
    private String buildPath(int workerId) {
        return PATH_PREFIX + applicationName + PATH_SEPARATOR + workerId;
    }
}
